package deepbrain.simnetwork.structure;

import deepbrain.simnetwork.exception.SimNetworkException;
import deepbrain.simnetwork.exception.SimNetworkRuntimeException;

/**
 * 
 * 
 * @author Li Yang
 * @create 2009-2-23
 */
public class ConnectionMatrix<WeightType> extends Matrix<WeightType> implements
		Cloneable {

	private static final long serialVersionUID = 444676008097363703L;

	protected String NO_CONNECTION_SYMBOL = "0";

	@SuppressWarnings("unchecked")
	@Override
	public ConnectionMatrix<WeightType> clone() {
		try {
			ConnectionMatrix<WeightType> newMatrixType = (ConnectionMatrix<WeightType>) super
					.clone();
			newMatrixType.setMatrix(MatrixUtils.cloneMatrix(this.matrix,
					numOfRows, numOfCols));
			return newMatrixType;
		} catch (Exception e) {
			throw new SimNetworkRuntimeException(e);
		}
	}

	@Override
	public String getMatrixType() {
		return "Connection Matrix";
	}

	public ConnectionMatrix() {
		super();
	}

	public ConnectionMatrix(Object[][] matrix) throws SimNetworkException {
		super(matrix);
	}

	public ConnectionMatrix(String parseLine) throws SimNetworkException {
		super(parseLine);
	}

	@SuppressWarnings("unchecked")
	public void initialize(int numOfNodes) {
		this.numOfRows = numOfNodes;
		this.numOfCols = numOfNodes;
		matrix = (WeightType[][]) new Object[numOfNodes][numOfNodes];
	}

	public WeightType translateToWeightTypeExceptionNest(String weight)
			throws SimNetworkException {
		if (weight == null || weight.equals(NO_CONNECTION_SYMBOL))
			return null;
		try {
			return parseWeight(weight);
		} catch (RuntimeException e) {
			throw new SimNetworkException(
					"Cannot Parse the Weight Type of Weight: " + weight, e);
		}
	}

	protected boolean validateMatrix(Object[][] matrix) {
		if (matrix == null || matrix.length == 0)
			return false;

		int numOfRows = matrix.length;

		for (Object[] row : matrix) {
			if (row.length != numOfRows)
				return false;
		}

		return true;
	};

	protected String getMatrixAsString(Object[][] matrix) {
		StringBuilder builder = new StringBuilder(
				MatrixUtils.STRING_BUILDER_INITIAL_SIZE);
		builder.append("\t");
		int colNum = matrix[0].length;
		for (int i = 1; i <= colNum; i++) {
			builder.append(i);
			builder.append(":");
			builder.append("\t");
		}
		builder.append("\n");
		int rowNum = 0;
		for (Object[] row : matrix) {
			rowNum++;
			builder.append("[");
			builder.append(rowNum);
			builder.append("]");
			builder.append("\t");
			for (Object element : row) {
				if (element == null)
					builder.append(NO_CONNECTION_SYMBOL);
				else
					builder.append(element);
				builder.append("\t");
			}
			builder.append("\n");
		}
		return builder.toString();
	}

	@Override
	public WeightType parseWeight(String weight) throws SimNetworkException {
		return null;
	}

	@Override
	public String serializeWeight(WeightType weight) {
		if (weight == null)
			return NO_CONNECTION_SYMBOL;
		return weight.toString();
	}

}
